package cn.dengta.webapp.user.service;

import java.util.Date;
import javax.servlet.http.*;

import cn.dengta.common.context.I18N;
import cn.dengta.common.model.Messager;
import cn.dengta.common.web.Page;
import cn.dengta.context.model.*;
import cn.dengta.context.web.RequestContextImpl;
import cn.dengta.webapp.user.dao.ProxyAccountDao;
import cn.dengta.webapp.user.entity.*;
import cn.dengta.webapp.user.form.UserLoginForm;
import cn.dengta.webapp.user.model.CredentialType;
import cn.dengta.webapp.user.model.LoginLogEntry;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import me.codeplayer.util.ArrayUtil;
import me.codeplayer.util.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
public class ProxyAccountService extends MemberServiceImpl<ProxyAccount, ProxyAccountDao> {

	public static final String SESSION_PROXY = "sessionProxy";

	@Override
	protected void logErrorLogin(String identity) {
	}

	@Override
	protected void saveLoginLog(LoginLogEntry entry) {
	}

	@Override
	public Messager<ProxyAccount> loginInternal(UserLoginForm form) {
		CredentialType type = CredentialType.USERNAME;
		ProxyAccount proxyAccount = getByCredential(form.getUsername(), type);
		Messager<ProxyAccount> msger;
		if (proxyAccount == null) {
			msger = Messager.status(Messager.NULL, I18N.msg(UserI18nKey.USER_NONENTITY, RequestContextImpl.doGetLanguage(RequestContextImpl.get().getRequest()).getLocale()));
		} else if (proxyAccount.checkPassword(form.getPassword(), false)) {
			msger = Messager.hideData(proxyAccount);
		} else {
			return Messager.status(MemberContent.STATUS_LOGIN_ERROR, I18N.msg(UserI18nKey.USER_PASSWORD_ERROR_RESUME_LOAD, RequestContextImpl.doGetLanguage(RequestContextImpl.get().getRequest()).getLocale()));
		}
		return loginAfter(form, msger);
	}

	/**
	 * 登录成功后后处理
	 */
	@Override
	public Messager<ProxyAccount> loginAfter(UserLoginForm form, Messager<ProxyAccount> msger) {
		if (!msger.isOK()) {
			logErrorLogin(form.username);
			return msger;
		}
		final ProxyAccount user = msger.data();
		if (user.isDestroyed()) {
			return msger.setMsg(I18N.msg(UserI18nKey.USER_DESTROY, RequestContextImpl.doGetLanguage(RequestContextImpl.get().getRequest()).getLocale())).setERROR();
		}
		FreezeTip freezeTip = user.getFreezeTip();
		if (StringUtil.notEmpty(freezeTip)) { // 冻结
			return msger.setMsg(freezeTip.getTip()).setStatus(MessagerStatus.LOGIN)
					.setExtra(freezeTip.getExtra(RequestContextImpl.doGetLanguage(RequestContextImpl.get().getRequest()).getLocale())).setCode(Messager.ERROR_CODE).setCallback(Messager.CALLBACK_ALERT);
		}
		if (!user.canLogin() || (form.fromBackstage && !user.canLoginBackstage())) {
			return msger.setMsg(I18N.msg(UserI18nKey.USER_FROZEN, RequestContextImpl.doGetLanguage(RequestContextImpl.get().getRequest()).getLocale())).setStatus(MessagerStatus.FROZEN).setCode(Messager.ERROR_CODE);
		}
		// 保存 user 到 session
		final RequestContextImpl req = RequestContextImpl.get();
		final Date now = req.now();
		// 最后一次登录时间
		user.setLastLoginTime(now);
		final HttpServletRequest request = req.getRequest();
		user.setSessionId(request == null ? req.getSessionId() : request.getSession().getId());
		final String loginIp = req.clientIP();
		if (!form.fromBackstage) {
			Country country;
			if (!user.hasFlag(User.BIZ_FLAG_FROM_CHINA) && (country = queryCountryByIp(loginIp)) != null
					&& ArrayUtil.ins(country, Country.ALL_CHINA)) {
				user.addFlag(User.BIZ_FLAG_FROM_CHINA);
			}
		}
		super.update(user);
		req.sessionAttr(SESSION_PROXY, user);
		if (user.hasChangeLanguage() || user.isAdmin()) {
			req.sessionContext().setLanguage(user.getLanguage());
		}
		return msger;
	}

	public Page<ProxyAccount> list(Page<ProxyAccount> page) {
		return this.selectPage(page, new QueryWrapper<>());
	}

	@Transactional(propagation = Propagation.SUPPORTS)
	public Messager<ProxyAccount> getLoginAccount(HttpServletRequest request, HttpServletResponse response) {
		HttpSession session = request.getSession(false);
		ProxyAccount account = null;
		if (session != null) {
			account = (ProxyAccount) session.getAttribute(SESSION_PROXY);
		}
		// 如果是 AJAX 提交，响应 JSON
		if (account == null) {
			return new Messager<>(MessagerStatus.LOGIN, I18N.msg(UserI18nKey.USER_AUTO_LOGIN_INVALID, RequestContextImpl.doGetLanguage(request).getLocale()), "");
		}
		return Messager.exposeData(account);
	}

}
